package blogger.server.services;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import blogger.client.async.GetTwitsResponse;
import blogger.client.async.services.TwitService;
import blogger.client.model.entity.Message;
import blogger.client.model.entity.User;
import blogger.model.entity.MessageEntity;
import blogger.model.entity.UserEntity;
import blogger.model.utils.EMF;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * The server side implementation of the RPC service.
 */
public class TwitServiceImpl extends RemoteServiceServlet implements TwitService {

    public GetTwitsResponse lastTwits(Date time) {
        List<Message> messages = new LinkedList<Message>();
        List<User> users = new LinkedList<User>();
        List<MessageEntity> messageEntities = null;
        EntityManager em = EMF.get().createEntityManager();
        try {
            Query query = em.createQuery("SELECT m FROM MessageEntity m WHERE m.date > :time ORDER BY m.date");
            query.setParameter("time", time);
            query.setMaxResults(10);
            try {
                messageEntities = query.getResultList();
                for (MessageEntity m : messageEntities){
                    messages.add(m.toGwtTwit());
                    Query q = em.createQuery("select u from UserEntity u where u.id = :uid");
                    q.setParameter("uid",m.getUser_id());
                    UserEntity userEntity = (UserEntity) q.getSingleResult();
                    users.add(userEntity.toUserGwt());
                }
            } catch (NoResultException e) {
                return null;
            }
        } finally {
            em.close();
        }
        if(messages.size() == 0)
            return null;
        else
            return new GetTwitsResponse(messages,users);

    }

    public Message twitMessage(Message msg) {
        HttpServletRequest request = this.getThreadLocalRequest();
        HttpServletResponse response = this.getThreadLocalResponse();
        HttpSession session = request.getSession();
        Long id = (Long) session.getAttribute("id");
        if (id != null) {
            MessageEntity message = new MessageEntity(id, msg.getText(),new Date());
            EntityManager em = EMF.get().createEntityManager();
            try {
                em.persist(message);
            } finally {
                em.close();
            }
            return message.toGwtTwit();
        }
        return null;
    }

    public void deleteTwit(long id) {
        EntityManager em = EMF.get().createEntityManager();
        Query query = em.createQuery("delete from MessageEntity m where m.id = :mid");
        query.setParameter("mid",id);
        query.executeUpdate();
    }

    public GetTwitsResponse getTwits() {
        EntityManager em = EMF.get().createEntityManager();
        List<Message> messages = new LinkedList<Message>();
        List<UserEntity> userEntities = null;
        List<User> users = new LinkedList<User>();
        List<MessageEntity> messageEntities = null;
        Query query = em.createQuery("SELECT m FROM MessageEntity m ORDER BY m.date DESC ");
        query.setMaxResults(10);
        try{
            messageEntities = (List<MessageEntity>) query.getResultList();
        }catch (NoResultException e) {
            return null;
        }
        for (MessageEntity msg : messageEntities) {
            messages.add(msg.toGwtTwit());
            Query query1 = em.createQuery("select u from UserEntity u where u.id = :uid");
            query1.setParameter("uid",msg.getUser_id());
            UserEntity userEntity = (UserEntity) query1.getSingleResult();
            users.add(userEntity.toUserGwt());
        }
        return new GetTwitsResponse(messages,users);
    }

}
